--
-- Author: shunguo.chen
-- Date: 2017-01-10 11:08:08
--
-- PlayerController


local AvatarPreView = import("..views.AvatarPreView")
local PlayerLvUpView = import("..views.PlayerLvUpView")
local PlayerLvUpActView = import("..views.PlayerLvUpActView")
local PlayerExpBar = import("..views.PlayerExpBar")
local ExplockView = import("..views.ExplockView")
local WithTipsView = require("app.newFloatTips.WithTipsView")

local Daibi = require("app.public.dao.Daibi")

local fileName = string.getModeName(...)
local ClassRef = class(fileName, app.mvc.ControllerBase)

function ClassRef:ctor(params)
	self.super.ctor(self, params)

end

function ClassRef:init()
	self._model = app:getInst("PlayerModel")

	self._expBar = nil

	-- 是否可以获得经验
	self._getExpEnable = true
	self._expCache = 0

	-- 改变的等级(用来避免在剧情中弹升级框)
	self._levelCache = nil
	self._stepDatas = nil

	-- 是否在升级动画中，在其中不能出现其他的toast，会遮挡
	self._isInLvUpAct = false

	self._playerHandler = UD.player:onChanged(handler(self, self.updatePlayer))
	self._bagHandler = UD.bag:onChanged(handler(self, self.updateBag))
	self._walletHandler = UD:onChanged("wallet", handler(self, self.updateWallet))
	self._equipHandler = UD:onChanged("equip", handler(self, self.updateEquip))
	self._equipGridHandler = UD:onChanged("equipGrid", handler(self, self.updateEquipGrid))
	self._mountSoulHandler = UD:onChanged("mountSoul",handler(self, self.updateMountSoul))
	self._partnerSoulHandler = UD:onChanged("partnerSoul",handler(self, self.updatePartnerSoul))
end

function ClassRef:removeListeners()
	self.super.removeListeners(self)

	UD.player:unChanged(self._playerHandler)
	UD.bag:unChanged(self._bagHandler)
	UD:unChanged("wallet", self._walletHandler)
	UD:unChanged("equip", self._equipHandler)
	UD:unChanged("equipGrid", self._equipGridHandler)
	UD:unChanged("mountSoul", self._mountSoulHandler)
	UD:unChanged("partnerSoul", self._partnerSoulHandler)
end

function ClassRef:listEvent()
	return {
		"avatarPreview",
		"OnGameConnected",
		"OnRoleCreated"
	}
end


function ClassRef:onEvent(eventName, data)
	if eventName == "OnGameConnected" then
		if self._expBar then
			self._expBar:setWorldLock(UD:getExpPool())
			self._expBar:setData(self._model:getInitExpData())
			self._expBar:refresh()
		end
	elseif eventName == "avatarPreview" then
		self:openAvatarPreView(data)
	elseif eventName == "OnRoleCreated" then
		self:addOnLinePushNotice()
	end
end

function ClassRef:openView(data)


end
function ClassRef:closeView(data)

end
function ClassRef:clearView(data)

end

-- show经验条，一般在imBubbleZOrder，有些系统界面需要显示经验条，需要在upExpBarZOrder
function ClassRef:showExpBar(zOrder)
	zOrder = zOrder or SceneZOrder.imBubbleZOrder
	if not self._expBar then
		self._expBar = PlayerExpBar.create()
		self._expBar:setWorldLock(UD:getExpPool())
		self._expBar:setData(self._model:getInitExpData())
        self._expBar:refresh()
		self._expBar:setName("PlayerExpBar")
		UIHandler:addChildToUiParent(self._expBar)
	end
	self._expBar:setLocalZOrder(zOrder)
	self._expBar:show()
end

-- hide经验条
function ClassRef:hideExpBar()
	if self._expBar then
		self._expBar:hide()
	end
end

function ClassRef:getExpBar()
	return self._expBar
end

-- 是否立即处理获得经验，不能需要把经验缓存起来
function ClassRef:setGetExpEnable(b)
	self._getExpEnable = b
	if b and self._expCache > 0 then
		self:onGetExp({exp = self._expCache})
		self._expCache = 0
	end
end

-- 升级奖励界面
function ClassRef:showPlayerLvUpView(level)
	-- 升级界面可能多个，只保存一个，移除前一个
	UIHandler:removePopupUiByKey(PlayerLvUpView:getViewName())

	local view = PlayerLvUpView.new()
	view:onCloseView(function(sender)
    	UIHandler:removePopupUiByKey(sender:getViewName())

    	-- 通知移除桌面tips
        local params = {
            remindId = 100001,
            dataTemp = level
        }
		UIHandler:getDesktopController():removeFourthTips( params )
    end)
	view:onClearView(function()
			self:showExpBar()
			self._expBar:stepOver()
		end)
	view:refresh(self._model:getLvUpShowData(level))
	UIHandler:addPopupUi(view, view:getViewName())
	view:show()
	self:showExpBar(SceneZOrder.popupUIZOrder+1)
end

function ClassRef:isInLvUpAct()
	return self._isInLvUpAct
end

-- 升级动画
function ClassRef:showPlayerLvUpActView(level)
	self._isInLvUpAct = true
	local view = PlayerLvUpActView.new(app.mvc.VIEWTYPE_NORMAL)
	view:onClearView(function()
			self._isInLvUpAct = false
		end)
	view:refresh(level)
	UIHandler:getDesktopController():addChild(view)
	view:show()

	view:performWithDelay(function()
		self._isInLvUpAct = false
	end, 0.5)

	-- 播放角色升级特效
	FieldManager:onLevelUpAnimation()
end

-- 世界锁界面
function ClassRef:showWorldExpLockView(level)
	self._model:C2S_WorldExpLock(function(msg)
		-- print("$$$$$$$$$$$  获取经验锁  ",msg.lockLevel)
		-- print("$$$$$$$$$$$  获取经验锁  ",msg.expPool)
		-- print("$$$$$$$$$$$  获取经验锁  ",msg.unlockTime)
		local name = ExplockView:getViewName()
		if UIHandler:getSystemUiByKey(name) then
			UIHandler:removeSystemUiByKey(name)
		end
		local view = ExplockView.new()
		view:onCloseView(function(sender)
			UIHandler:removeSystemUiByKey(name)
		end)

		view:freshData(msg)
		UIHandler:addSystemUi(view, view:getViewName())
		view:show()	

	end) 
end
-- 外显预览界面
-- params = {
-- 	type = Enums.AvatarPreviewType,
-- 	id = equipId/mountId/npcId
-- }
function ClassRef:openAvatarPreView(params)
	local view = AvatarPreView.new()
	view:onCloseView(function(sender)
		UIHandler:removePopupUiByKey(sender:getViewName())
	end)
	local avatarParams
	if params.type == Enums.AvatarPreviewType.equip then
		avatarParams = UD:getAvatarParams()
		avatarParams.mountID = nil
		avatarParams.fashionIDs = GD:attachPreviewFashionId(avatarParams.fashionIDs, params.id)
	end
	view:refresh(params, avatarParams)
	UIHandler:addPopupUi(view, view:getViewName())
	view:show()
end

-- 添加本地推送消息
-- param = id or conf pigeon
function ClassRef:addPushNotice(param, time)
	local conf
	if type(param) == "number" then
		conf = GD:getPigeonConfById(param)
	else
		conf = param
	end
	local userLv = UD:getLevel()
	if tonumber(conf.lv) <= userLv then
		if not time then
			local timeAry = table.tonumber(string.split(conf.time, ":"))
			time = timeAry[1] * 3600 + timeAry[2] * 60
		end

		local params = {}
		params.dataType = tonumber(conf.type)
		params.time = time
		params.UTC = app.session:getLocalTimeZone()
		if app:isIOS() then
			params.msg = L(conf.contentIos)
		elseif app:isAndroid() then
			params.className = "org.cocos2dx.lua.AppActivity"
			params.msg = L(conf.contentAndroid)
			params.title = L(conf.titleAndroid)
			params.pushType = tonumber(conf.ID)
			params.titleType = 1
		end
		-- dump(params, "addPushNotice " .. conf.ID)
		app.channelAPI:savePushData(params)
	end
end

function ClassRef:_checkLvPushNotice(lv)
	local confs = GD:getPigeonConfs()
	for i,conf in ipairs(confs) do
		if tonumber(conf.lv) == lv then
			if conf.extraLimit == "0" then
				self:addPushNotice(conf)
			end
		end
	end
end

-- 创角时添加本地推送
function ClassRef:addOnLinePushNotice()
	local time1, time2 -- 时间以凌晨5点为分界点
	local date = os.date("*t", os.time())
	-- dump(date, "push date")
	local extraTime = date.hour >= 5 and 24*3600 or 0
	local conf1 = GD:getPigeonConfById(1009)
	if conf1 then
		local timeAry = table.tonumber(string.split(conf1.time, ":"))
		time1 = timeAry[1] * 3600 + timeAry[2] * 60 + extraTime
	end
	local conf2 = GD:getPigeonConfById(1010)
	if conf2 then
		local timeAry = table.tonumber(string.split(conf2.time, ":"))
		time2 = timeAry[1] * 3600 + timeAry[2] * 60 + extraTime + 24*3600
	end
	if time1 then
		self:addPushNotice(1009, time1) -- 第二天上线提醒
	end
	if time2 then
		self:addPushNotice(1010, time2) -- 第三天上线提醒
	end
end

-- 剧情结束，显示升级界面
function ClassRef:storyOver()
	if self._levelCache then
		self._expBar:showGetExp(self._stepDatas)
		-- self:showPlayerLvUpView(self._levelCache)
		self:showPlayerLvUpActView(self._levelCache)
		self._levelCache = nil
		self._stepDatas = nil
	end
end

----------------------------------------------
function ClassRef:onGetExp(ret)
	local exp = ret.exp

	if not self._getExpEnable then
		self._expCache = self._expCache + exp
		return
	end

	if not self._expBar then return end
	local data = self._expBar:getData()
	local stepDatas = self._model:getExpStepDatas(data, exp)
	self._expBar:setData(stepDatas[#stepDatas])
	-- 1. 如果升级，升级框和经验条动画一起出来
	local firstData = stepDatas[1]
	local lastData = stepDatas[#stepDatas]

	if self._stepDatas then
		for i=2,#stepDatas do
			self._stepDatas[#self._stepDatas + 1] = stepDatas[i]
		end

		self._levelCache = lastData.level
		return
	end

	if lastData.level > firstData.level then
		if BattleManager:isBattle() or StoryManager:isEnterStoryMode() then
			-- 在剧情中，缓存等级等剧情结束再显示升级界面
			self._levelCache = lastData.level
			--if self._stepDatas then
				--for i=2,#stepDatas do
					--self._stepDatas[#self._stepDatas + 1] = stepDatas[i]
				--end
			--else
				self._stepDatas = stepDatas
			--end
			DelayStack:pushToFront({name = "levelUp"})
		else
			self._expBar:showGetExp(stepDatas)
			-- self:showPlayerLvUpView(lastData.level)
			self:showPlayerLvUpActView(lastData.level)
		end
	else
		self._expBar:showGetExp(stepDatas)
	end

	-- 2. 如果升级，经验条动画结束再出来升级框（因为有延迟会有各种问题，暂时不用）
	-- self._expBar:showGetExp(stepDatas, function()
	-- 	local firstData = stepDatas[1]
	-- 	local lastData = stepDatas[#stepDatas]
	-- 	if lastData.level > firstData.level then
	-- 		if BattleManager:isBattle() or StoryManager:isEnterStoryMode() then
	-- 			-- 在剧情中，缓存等级等剧情结束再显示升级界面
	-- 			self._levelCache = lastData.level
	-- 			DelayStack:pushToFront({name = "levelUp"})
	-- 		else
	-- 			self:showPlayerLvUpView(lastData.level)
	-- 		end
	-- 	end
	-- end)
end

-- player更新
function ClassRef:updatePlayer(name, old, new)
	if name == "expAndLevel" then
		--这里计算如何显示经验条
		local addExp = 0
		if old.level == new.level then
			addExp = new.exp - old.exp
		else
			for i = old.level, new.level do
				if i == old.level then
					local conf = GD:queryHeroLevelUpByLevel(i)
					addExp = addExp + tonumber(conf.exp) - old.exp
				elseif i == new.level then
					addExp = addExp + new.exp
				else
					local conf = GD:queryHeroLevelUpByLevel(i)
					addExp = addExp + tonumber(conf.exp)
				end
			end
			--升级了 需要做一下经验锁奖励更新的处理，世界经验锁的bUFF奖励描述也不一样
		end
		self:onGetExp({exp = addExp})
	elseif name == "combatPower" then
		DelayStack:push({name=name, old=old, new=new})
	elseif name == "name" then
		FieldManager:updateMyCharacterName()
	elseif name == "expPool" then
		if self._expBar then
			self._expBar:setWorldLock(UD:getExpPool())
		end
    elseif name == "level" then
        --判断等级是否达到世界boss开放等级，如果达到再请求一次世界boss开启状态
        local openLv = GD:getWorldBossOpenLevel()
        if new == openLv then
            app:getInst("BossModel"):reqWorldBossStatus()
        end

        self:_checkLvPushNotice(new)

        UD.redPoint:checkStateByKey(RedPointConstant.Skill_Skill)
	end
end

-- 背包更新
function ClassRef:updateBag(uid,item,amountGot,opt)
	if amountGot <= 0 then return end
	if opt=="delete" or not item.isNew then return end

	if Enums.ItemBagType.equip == item.itemBagType then
	    DelayStack:pushToFront({name="item", item=item, num=amountGot})
	else
	    DelayStack:push({name="item", item=item, num=amountGot})
	end
end

-- 钱包更新，
function ClassRef:updateWallet(name, old, new, id)
	-- TODO csg 暂时屏蔽通知
	-- DelayStack:push({name=name, old=old, new=new})
	if name == "coin" or name == "gold" or name == "magicDust" or name == "magicCrystal" then
		-- 获得货币，需要播放获得动画
		local amountGot = new - old
		if amountGot > 0 then
			local item = Daibi.new()
			item:read({tid=id, amount=amountGot})
			DelayStack:push({name="item", item=item, num=amountGot})
		end
	end
end

-- 灵魂石更新
function ClassRef:updateMountSoul(id,mountSoul,amountGot,opt)
	if amountGot > 0 then
		DelayStack:push({name="item", item=mountSoul, num=amountGot})
	end
end

-- 灵魂石更新
function ClassRef:updatePartnerSoul(id,partnerSoul,partnerGot,opt)
	if partnerGot > 0 then
		DelayStack:push({name="item", item=partnerSoul, num=partnerGot})
	end
end

function ClassRef:updateEquip(uid,equip,opt)
	if opt ~= "update" then
		FieldManager:onChangeEquip(uid,equip,opt)
	end
end

function ClassRef:updateEquipGrid(equipGrid, preFashionId, hasAvatarChange, hasHiddenChange)
	FieldManager:onChangeEquipGrid(equipGrid, preFashionId, hasAvatarChange, hasHiddenChange)
end

---------------------------- view logic ---------------------------
--弹出健康提醒
function ClassRef:showWithTips(data)
	local tipsView = WithTipsView.new(app.mvc.VIEWTYPE_NORMAL,data)
	UIHandler:addPopupUi(tipsView,"WithTipsView" ,10000)
	tipsView:show()
end

return ClassRef
